#include<mpi.h>
#include<omp.h>
#include<stdio.h>
#define NUM_THREADS 1
static long num_steps=1000000000;
void main(int argc,char* argv[]){
    int i,myid,numprocs,start_i,end_i,res;
    double step;
    double x,pi=0.0,sum=0.0;
    double start_time,end_time;
    step=1.0/(double)num_steps;

    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD,&myid);
    MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
    MPI_Status status;

    res=num_steps%numprocs;

    if (res == 0) {
        start_i=myid*(num_steps/numprocs)+1 ;
        end_i=start_i + num_steps/numprocs-1;
    } else{
    if(myid == 0) {
        start_i = 1; 
        end_i = num_steps/numprocs;
        }
    else if(myid <= res) {
        start_i = myid*(num_steps/numprocs)+myid; 
        end_i = start_i + num_steps/numprocs; 
        }
    else if(myid > res) {
        start_i = myid*(num_steps/numprocs)+res+1;
        end_i = start_i + num_steps/numprocs-1;
        }
    }
    
    start_time=MPI_Wtime();

    omp_set_num_threads(NUM_THREADS);
    #pragma omp parallel for reduction(+:sum) private(x,i)
    for(i=start_i;i<=end_i;i++){
        x=(i-0.5)*step;
        sum+=4.0/(1.0+x*x);
    }
    
    MPI_Reduce(&sum,&pi,1,MPI_DOUBLE,MPI_SUM,0,MPI_COMM_WORLD);
    if(myid==0){
        printf("Pi的值为：%.20f\n",pi*step);
        end_time=MPI_Wtime();
        printf("程序运行时间：%f\n",end_time-start_time);
    }
    MPI_Finalize();
}
